feat(parity): port the JS points-to solver to native and unify engine resolution#1465
Conversation
Reorganize crates/codegraph-core/src/ so every module sits at the path of its TypeScript counterpart (snake_case for kebab-case): shared/, infrastructure/, db/repository/, domain/graph/builder/stages/, ast_analysis/, graph/algorithms/, graph/classifiers/, features/. - Pure git mv moves; only graph_algorithms.rs is split (bfs, shortest_path, centrality, louvain) along its existing section boundaries - lib.rs doc comment carries the full Rust<->TypeScript mapping table - Cross-references in TS sources, tests, and docs updated to new paths - Cargo.lock version synced to 3.12.0 (Cargo.toml was already bumped) - cargo test: 360 passed; tsc build and drift-guard test green
…nify per-engine resolution Native (Rust): - Extract all eight pts binding kinds in the JS extractor (param, this-call, array-element, spread-arg, for-of, array-callback, object-rest-param, object-prop) and surface them on FileSymbols - Run the same fixed-point points-to solver as the WASM path inside build_call_edges: thisCall-to-fnRef conversion, four-case key gate with receiver-key fallback, hop-penalised alias edges with pts upgrade - Normalize inline-new receivers (new A().t() -> receiver "A") in extract_receiver_name, mirroring extractReceiverName in the TS extractor - Apply the >=0.5 confidence filter on exact cross-file lookups (#1439) WASM/TS: - Plumb params and all eight binding arrays through NativeFileEntry so the hybrid path feeds the native solver - Serialize thisCallBindings across the WASM worker boundary - Backport the native engine's class-field type-annotation extraction (private repo: Repository seeds typeMap "repo"/"this.repo") - Remove the four JS pts post-passes that duplicated the native solver on the hybrid path (param-flow, fnRef, thisCall, object-rest) - Report the native build summary and build_meta counts after the JS edge-writing post-passes so they include CHA/this-dispatch edges (#1452) WASM, full-native orchestrator, and hybrid builds now produce identical edge multisets on the javascript fixture (155 rows each, including confidence and dynamic flags); javascript 42/42 and pts-javascript 13/13 expected edges on both engines; 392 Rust tests, 3043 JS tests, and the 176-test resolution benchmark are green. Closes #1453 Closes #1452 Closes #1439
|
Claude finished @carlos-alm's task —— View job PR Review: feat(parity): port the JS points-to solver to native and unify engine resolutionRoot Cause AnalysisProblem Being Solved: Native (Rust) engine resolved only 36/42 expected JS edges and 3/13 pts-javascript edges (#1453), while WASM resolved 42/42 and 13/13. The root cause was two-fold: (1) the JS extractor never surfaced its eight pts binding kinds to Why This Approach: The PR takes the correct architectural approach — fix the root cause (missing pts extraction + missing solver) rather than hiding the discrepancy. It ports the full fixed-point pts solver from TS to Rust, backports a class-field type-annotation extraction gap to TS, removes the now-redundant JS post-passes, and ensures the WASM worker serializes Risk Assessment: Medium. The change is large (2150 additions) but focused on a single subsystem (pts resolution). The PR claims identical edge multisets across all three paths with 3043 passing JS tests + 392 Rust tests + 176-benchmark green. The duplicate-builtin-globals list and a Phase 2: Configuration Change DetectionNo linting rules, TypeScript flags, test timeouts, or coverage thresholds were modified. Clean. Phase 3: Test IntegrityTest changes ( Phase 4: Code Quality ConcernsBug:
|
Codegraph Impact Analysis89 functions changed → 401 callers affected across 46 files
|
Greptile SummaryThis PR brings the native Rust and WASM/TS engines to full JavaScript resolution parity by porting the complete points-to solver to Rust and eliminating the duplicated TS post-passes from the hybrid path. The result is a single source of truth for pts resolution per engine path, verified by identical 155-edge multisets across all three build modes.
Confidence Score: 5/5Safe to merge — all three engine paths produce identical edge multisets on the JS fixture, and no regressions were found in the 3600+ test suite. The algorithmic changes are thoroughly tested (392 Rust, 3043 JS, 176 benchmark), the removed TS post-passes are provably replaced by the native solver (zero edge-multiset divergence across all three build modes), and the thisCallBindings worker-boundary fix closes a previously silent data-loss path. No logic errors or missing invariants were identified in the pts solver, the fixed-point termination, or the pts-upgrade mechanism. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
subgraph Native["Full-Native Path (Rust)"]
N1[parse JS files\nJsExtractor] --> N2[8 pts binding kinds\ncollected in FileSymbols]
N2 --> N3[Phase 8.2\npropagate_return_types\n_across_files]
N3 --> N4[build_call_edges\nfixed-point pts solver\n4-case key gate]
N4 --> N5[emit call / receiver /\nhierarchy edges]
end
subgraph Hybrid["Hybrid Path (WASM parse + native edges)"]
H1[WASM worker parses JS\nthisCallBindings serialized\nacross worker boundary] --> H2[NativeFileEntry\nparams + 8 binding arrays\npropagated]
H2 --> H3[Phase 8.2\npropagateReturnTypes\nAcrossFiles TS]
H3 --> H4[native buildCallEdges FFI\nsame Rust solver]
H4 --> H5[CHA / defineProperty\npost-passes JS only]
end
subgraph WASM["Pure WASM Path"]
W1[WASM worker parses] --> W2[buildPointsToMap TS]
W2 --> W3[buildFileCallEdges TS\n4-case key gate]
W3 --> W4[CHA / other post-passes]
end
N5 & H5 & W4 --> DB[(edges table)]
Reviews (5): Last reviewed commit: "fix(native): add safety comment on max_i..." | Re-trigger Greptile |
… Rust orchestrator The JS pipeline seeds each file's typeMap with the return types of imported factory functions (propagateReturnTypesAcrossFiles) before edge resolution, so `const svc = buildService(); svc.createUser()` resolves across files. The Rust orchestrator extracted returnTypeMap and callAssignments but never consumed them, dropping those calls and receiver edges on the native path (hybrid was unaffected because the JS pipeline pre-seeds the typeMap it sends over napi). Mirror the JS pass in pipeline.rs: build a per-file + global return-type index, resolve each call assignment through the file's imports (or the qualified Type.method global map), and inject typeMap entries at confidence minus PROPAGATION_HOP_PENALTY, never overwriting locally typed variables. Verified with scripts/parity-compare.mjs: the javascript fixture now matches exactly across wasm/native/hybrid (180 edges incl. driver.mjs conf=0.7 calls + conf=0.75 receiver edges).
|
Addressed Claude's review feedback:
|
|
Addressed all remaining feedback from the initial Claude review:
|
|
Claude finished @carlos-alm's task —— View job Re-review: feat(parity): port the JS points-to solver to native and unify engine resolutionVerifying fixes from initial review
Verification Results
|
Summary
Brings the native (Rust) and WASM (TS) engines to full resolution parity on the JavaScript fixture set, taking the best of both implementations rather than restricting changes to one language. Stacked on #1463 (mirrored module layout).
Native (Rust) — JS→native port:
param,this-call,array-element,spread-arg,for-of,array-callback,object-rest-param,object-prop) and surfaces them onFileSymbols.build_call_edgesruns the same fixed-point points-to solver as the WASM path: thisCall→fnRef conversion, the four-case key gate with receiver-key fallback, and hop-penalised alias edges with the pts upgrade mechanism.new A().t()→ receiver"A") inextract_receiver_name, mirroringextractReceiverNamein the TS extractor.WASM/TS — native→JS backport and cleanup:
NativeFileEntryplumbsparamsand the eight binding arrays so the hybrid path feeds the native solver;thisCallBindingsis serialized across the WASM worker boundary.private repo: Repositoryseeds typeMaprepo/this.repo).build_metacounts are now reported after the JS edge-writing post-passes, so they include CHA/this-dispatch edges.Verification
confidenceanddynamicflags.Closes #1453
Closes #1452
Closes #1439
Test plan
cargo test— 392 passed